package SecondeStage.FanXing;


import java.util.ArrayList;
import java.util.List;

public class GenericDetil {
    public static void main(String[] args) {
        // 1. 给泛型指向数据类型，要求是引用类型，不能是基本数据类型
        List<Integer> list =new ArrayList<Integer>(); //ok
        //List<Integer> list2 =new ArrayList<int>(); //错

        // 2.给泛型指定具体类型后，可以传入该类型的子类型
        pig<A> apig = new pig<A>(new A());
        apig.f();
        pig<A> apig2 = new pig<A>(new B()); //可以接收A的子类型
        apig2.f();

        // 3.泛型的使用形式
        ArrayList<Integer> list2 = new ArrayList<Integer>();
        List<Integer> list3 = new ArrayList<Integer>();
        // 在实际开发中，往往简写，编译器会自动进行类型推断
        ArrayList<Integer> list4 = new ArrayList<>();
        List<Integer> list5 = new ArrayList<>();

        // 4.这样写，默认泛型是Object
        ArrayList objects = new ArrayList();
    }
}

class A{}
class B extends A{}

class pig<E>{
    E e;

    public pig(E e) {
        this.e = e;
    }

    public void f(){
        System.out.println(e.getClass());
    }
}
// Pig后面有泛型,所以我们把pig成为自定义泛型类
// E,T,R,M 泛型的标识符，一般是单个大写字母
class tiger<E,T,R,M>{
    E e;
    R r;
    T t;
    M m;

    // 使用泛型的数组不能初始化,因为数组在new的时候不能确定T的类型，所以无法在内存开空间
    //T[] ts =new T[8];

    // 静态方法不能使用泛型,因为静态是和类相关的，在类加载时对象还没有创建，而泛型是在对象创建时才指定数据类型
    // 所以如果静态方法和静态属性使用了泛型，JVM就无法完成初始化
    //public static void f(M m){}

    // 构造器使用泛型
    public tiger(E e, R r, T t, M m) {
        this.e = e;
        this.r = r;
        this.t = t;
        this.m = m;
    }
    // 方法和返回类型使用泛型
    public E getE() {
        return e;
    }

    public void setE(E e) {
        this.e = e;
    }

    public R getR() {
        return r;
    }

    public void setR(R r) {
        this.r = r;
    }

    public T getT() {
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }

    public M getM() {
        return m;
    }

    public void setM(M m) {
        this.m = m;
    }
}